package xyz.ylx.apirotation.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.ConnectionProvider;

import org.springframework.util.StringUtils;

import java.time.Duration;

import lombok.extern.slf4j.Slf4j;

/**
 * API路由配置
 */
@Slf4j
@Configuration
public class ApiRoutingConfig {
    
    private static final String DEFAULT_GEMINI_OPENAI_URL = "https://generativelanguage.googleapis.com/v1beta/openai";
    private static final int DEFAULT_MAX_BUFFER_SIZE = 16 * 1024 * 1024; // 16MB
    private static final int DEFAULT_TIMEOUT_SECONDS = 60;
    private static final int MAX_CONNECTIONS = 50;
    private static final long ACQUIRE_TIMEOUT_MILLIS = 30000;
    
    @Value("${openai.api.url}")
    private String openaiApiUrl;
    
    @Autowired
    private GeminiApiKeyConfig geminiApiKeyConfig;
    
    /**
     * 设置更大的缓冲区大小，以处理大型响应
     */
    private ExchangeStrategies createLargeResponseStrategies() {
        return ExchangeStrategies.builder()
                .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(DEFAULT_MAX_BUFFER_SIZE))
                .build();
    }
    
    /**
     * 请求/响应日志过滤器
     */
    private ExchangeFilterFunction logRequest() {
        return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
            log.debug("请求: {} {}", clientRequest.method(), clientRequest.url());
            clientRequest.headers().forEach((name, values) -> 
                values.forEach(value -> log.debug("{}={}", name, value))
            );
            return Mono.just(clientRequest);
        });
    }
    
    /**
     * 创建连接池提供器
     */
    private ConnectionProvider createConnectionProvider() {
        return ConnectionProvider.builder("api-connection-pool")
                .maxConnections(MAX_CONNECTIONS)
                .pendingAcquireTimeout(Duration.ofMillis(ACQUIRE_TIMEOUT_MILLIS))
                .build();
    }
    
    /**
     * 创建通用的HttpClient配置
     */
    private HttpClient createHttpClient() {
        return HttpClient.create(createConnectionProvider())
                .responseTimeout(Duration.ofSeconds(DEFAULT_TIMEOUT_SECONDS))
                .keepAlive(true);
    }
    
    /**
     * OpenAI API WebClient
     */
    @Bean
    public WebClient openaiWebClient() {
        String baseUrl = StringUtils.hasLength(openaiApiUrl) ? 
                openaiApiUrl : "https://api.openai.com/v1";
                
        log.info("创建OpenAI WebClient，基础URL: {}", baseUrl);
        
        return WebClient.builder()
                .baseUrl(baseUrl)
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .exchangeStrategies(createLargeResponseStrategies())
                .filter(logRequest())
                .clientConnector(new ReactorClientHttpConnector(createHttpClient()))
                .build();
    }
    
    /**
     * Gemini API WebClient
     */
    @Bean
    public WebClient geminiWebClient() {
        String geminiOpenaiUrl = geminiApiKeyConfig.getOpenaiUrl();
        
        if (!StringUtils.hasLength(geminiOpenaiUrl)) {
            log.warn("未配置Gemini OpenAI兼容URL，使用默认配置: {}", DEFAULT_GEMINI_OPENAI_URL);
            geminiOpenaiUrl = DEFAULT_GEMINI_OPENAI_URL;
        }
        
        // 确保URL不以斜杠结尾，这样我们可以始终使用 .uri("/path") 格式
        if (geminiOpenaiUrl.endsWith("/")) {
            geminiOpenaiUrl = geminiOpenaiUrl.substring(0, geminiOpenaiUrl.length() - 1);
        }
        
        log.info("创建Gemini WebClient，基础URL: {}", geminiOpenaiUrl);
        
        return WebClient.builder()
                .baseUrl(geminiOpenaiUrl)
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .defaultHeader(HttpHeaders.ACCEPT, MediaType.TEXT_EVENT_STREAM_VALUE)
                .defaultHeader(HttpHeaders.ACCEPT, "application/json")
                .defaultHeader(HttpHeaders.ACCEPT, "*/*")
                .exchangeStrategies(createLargeResponseStrategies())
                .filter(logRequest())
                .clientConnector(new ReactorClientHttpConnector(createHttpClient()))
                .build();
    }
    
    /**
     * 通用WebClient Builder
     */
    @Bean
    public WebClient.Builder webClientBuilder() {
        return WebClient.builder()
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .exchangeStrategies(createLargeResponseStrategies())
                .filter(logRequest())
                .clientConnector(new ReactorClientHttpConnector(createHttpClient()));
    }
} 